//--------------------------------------------------------------
//
// Qizhi Zhang 
// ezhung@gmail.com
// http://www.moorwind.com
//
//--------------------------------------------------------------
package reader.view
{
	import __AS3__.vec.Vector;
	
	import flash.events.Event;
	
	import org.puremvc.as3.multicore.interfaces.IMediator;
	import org.puremvc.as3.multicore.interfaces.INotification;
	
	import reader.ApplicationFacade;
	import reader.core.IGCAble;
	import reader.core.ReaderModelLocator;
	import reader.core.ReaderResource;
	import reader.core.UserConfirmCommandConfig;
	import reader.events.BlogItemEvent;
	import reader.events.BlogLabelEvent;
	import reader.events.BlogSourceEvent;
	import reader.events.UserEvent;
	import reader.model.IDataProxy;
	import reader.model.IUserProxy;
	import reader.model.vo.BlogDraftVO;
	import reader.model.vo.BlogFetchVO;
	import reader.model.vo.BlogItemVO;
	import reader.model.vo.BlogSourceVO;
	import reader.model.vo.TitleWindowVO;
	import reader.view.components.BlogListBox;
	import reader.view.components.BlogWriter;

	public class BlogListMediator extends BaseApplicationMediator implements IMediator, IGCAble
	{
		////////////////////////////////////////////////////////////////////////////////
		//public properties
		
		public static const NAME:String = "BlogListMediator";
		
		public function get blogListBox():BlogListBox
		{
			return this.viewComponent as BlogListBox;
		}
		
		////////////////////////////////////////////////////////////////////////////////
		//private variables
		private var dataProxy:IDataProxy;
		private var userProxy:IUserProxy;
		
		private var isFoolData:Boolean;	
		private var readerModelLocator:ReaderModelLocator = ReaderModelLocator.instance;
		
		//////////////////////////////////////////////////////////////////////////////
		//constructor
		public function BlogListMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
			
			startUp();
		}
		
		//////////////////////////////////////////////////////////////////////////////
		//methods
		
		public function startUp():void
		{
			dataProxy = facade.retrieveProxy(readerModelLocator.sqliteProxyFactory.dataProxyName) as IDataProxy;
			userProxy = facade.retrieveProxy(readerModelLocator.sqliteProxyFactory.userProxyName) as IUserProxy;
			
			blogListBox.addEventListener(BlogListBox.LIST_COMBO_CHANGE, onListComboxChange_handler, false, 0, true);
			blogListBox.addEventListener(BlogListBox.MARK_ALL_READ, onMarkAllRead_handler, false, 0, true);
			blogListBox.addEventListener(BlogListBox.REFRESH_BLOG, onFreshBlog_handler, false, 0, true);
			blogListBox.addEventListener(BlogListBox.SEARCH_BLOG, onSearchBlog_handler, false, 0, true);
			blogListBox.addEventListener(UserEvent.USER_IS_READ_NEW, onGetBlogTypeChange_handler, false, 0, true);
			blogListBox.addEventListener(BlogItemEvent.BLOG_ITEM_UPDATE, onBlogItemUpdate_handler, false, 0, true);
			blogListBox.addEventListener(BlogItemEvent.BLOG_ITEMS_UPDATE, onBlogItemsUpdate_handler, false, 0, true);
			blogListBox.addEventListener(BlogItemEvent.BLOG_ITEM_SHARE, onShareBlogItem_handler, false, 0, true);
			blogListBox.addEventListener(BlogSourceEvent.UPDATE_BLOG_SOURCE, onChangeBlogLabel_handler, false, 0, true);
			blogListBox.addEventListener(BlogSourceEvent.UNSUBSCRIBE, onUnSubscribe_handler, false, 0, true);
			blogListBox.addEventListener(BlogSourceEvent.QUICK_SUBSCRIBE, onQuickSubscribe_handler, false, 0, true);
			blogListBox.addEventListener(BlogLabelEvent.LABEL_CREATE, onCreateTag_handler, false, 0, true);
			blogListBox.addEventListener(BlogSourceEvent.UPDATE_BLOG_SOURCE_NAME, onChangeBlogSourceName_handler, false, 0, true);
			
			blogListBox.addEventListener(BlogItemEvent.OPEN_EXPLORER, onOpenExplore_handler);
		}
		
		public function clearReference():void
		{
			dataProxy = null;
			userProxy = null;
			
			blogListBox.removeEventListener(BlogListBox.LIST_COMBO_CHANGE, onListComboxChange_handler);
			blogListBox.removeEventListener(BlogListBox.MARK_ALL_READ, onMarkAllRead_handler);
			blogListBox.removeEventListener(BlogListBox.REFRESH_BLOG, onFreshBlog_handler);
			blogListBox.removeEventListener(BlogListBox.SEARCH_BLOG, onSearchBlog_handler);
			blogListBox.removeEventListener(UserEvent.USER_IS_READ_NEW, onGetBlogTypeChange_handler);
			blogListBox.removeEventListener(BlogItemEvent.BLOG_ITEM_UPDATE, onBlogItemUpdate_handler);
			blogListBox.removeEventListener(BlogItemEvent.BLOG_ITEMS_UPDATE, onBlogItemsUpdate_handler);
			blogListBox.removeEventListener(BlogItemEvent.BLOG_ITEM_SHARE, onShareBlogItem_handler);
			blogListBox.removeEventListener(BlogSourceEvent.UPDATE_BLOG_SOURCE, onChangeBlogLabel_handler);
			blogListBox.removeEventListener(BlogSourceEvent.UNSUBSCRIBE, onUnSubscribe_handler);
			blogListBox.removeEventListener(BlogSourceEvent.QUICK_SUBSCRIBE, onQuickSubscribe_handler);
			blogListBox.removeEventListener(BlogLabelEvent.LABEL_CREATE, onCreateTag_handler);
			blogListBox.removeEventListener(BlogSourceEvent.UPDATE_BLOG_SOURCE_NAME, onChangeBlogSourceName_handler);
			
			blogListBox.removeEventListener(BlogItemEvent.OPEN_EXPLORER, onOpenExplore_handler);
			
			blogListBox.blogFetch = null;
			blogListBox.blogItemComboBoxList = [];
			blogListBox.blogSourceListDataProvider = null;
			
			facade.removeMediator(NAME);
		}
		override public function listNotificationInterests():Vector.<String>
		{
			return Vector.<String>([
					ApplicationFacade.BLOG_FETCH,
					ApplicationFacade.BLOG_FETCH_COMPLETE,
					ApplicationFacade.BLOG_FETCH_NULL,
					ApplicationFacade.BLOG_FETCH_ALL,
					ApplicationFacade.BLOG_SEARCH_RESULT,
					ApplicationFacade.REMOVED_SUBSCRIBE,
					ApplicationFacade.LOGOUT
					]);
		}
		
		override public function handleNotification(notification:INotification):void
		{
			switch(notification.getName())
			{
				case ApplicationFacade.BLOG_FETCH:
					resetBlogListState();					
					blogListBox.blogFetch = notification.getBody() as BlogFetchVO;
					dataProxy.fetchBlogs(blogListBox.blogFetch);
					onListComboxChange_handler();
					break;	
				case ApplicationFacade.BLOG_FETCH_COMPLETE:
					resetBlogListState();
					blogListBox.blogSourceListDataProvider = notification.getBody() as Vector.<BlogItemVO>;
					onListComboxChange_handler();
					break;
				case ApplicationFacade.BLOG_FETCH_NULL:
					blogListBox.currentState = readerModelLocator.user.isReadNew ? "noNewItems" : "noItems";	
					onListComboxChange_handler();
					break;
				case ApplicationFacade.BLOG_FETCH_ALL:
					blogListBox.blogFetch.blogsource.newBlogs = uint(notification.getBody());
					//CursorManager.removeBusyCursor();
					blogListBox.currentState = "allItems";
					break;
				case ApplicationFacade.BLOG_SEARCH_RESULT:
					resetBlogListState();
					var blogfetch:BlogFetchVO = notification.getBody() as BlogFetchVO;
					if(blogListBox.blogFetch.blogsource == blogfetch.blogsource || blogListBox.blogFetch.blogSourceIds == blogfetch.blogSourceIds)
					{
						blogListBox.blogSourceListDataProvider = blogfetch.blogItems ? blogfetch.blogItems : new Vector.<BlogItemVO>();
						blogListBox.currentState = "allItems";
					}					
					break;	
				case ApplicationFacade.REMOVED_SUBSCRIBE:
					var bs:BlogSourceVO = notification.getBody() as BlogSourceVO;
					if(blogListBox.blogFetch && bs.blogSourceId == blogListBox.blogFetch.blogsource.blogSourceId)
						blogListBox.currentState = "unsubscribed";
					break;
				case ApplicationFacade.LOGOUT:
					clearReference();
					break;		
			}
		}
		
		private function resetBlogListState():void
		{
			if(blogListBox.currentState || blogListBox.currentState != "")
				blogListBox.currentState = "";
			//CursorManager.removeBusyCursor();
		}
		
		//////////////////////////////////////////////////////////////////////////////
		//events
		
		private function onSearchBlog_handler(e:Event):void
		{
			dataProxy.searchBlog(blogListBox.blogFilterInput.text, blogListBox.blogFetch);
		}
		
		private function onFreshBlog_handler(e:Event):void
		{
			dataProxy.fetchBlogs(blogListBox.blogFetch);
			onListComboxChange_handler();
		}
				
		/**
		 * update user table, set isReadNew property, fetch new blogs or all blogs.
		*/
		private function onGetBlogTypeChange_handler(e:UserEvent):void
		{
			userProxy.updateUserGetBlogType(e.user);
			dataProxy.fetchBlogs(blogListBox.blogFetch);
		}
		
		/**
		 * open a panel for user to confirm wheather mark all items read.
		*/
		private function onMarkAllRead_handler(e:Event):void
		{
			if(readerModelLocator.user.isMarkAll)
			{
				var uf:UserConfirmCommandConfig = new UserConfirmCommandConfig(ReaderResource.instance.resource.blogItemTabMarkAllRead,			
					ReaderResource.instance.resource.blogItemTabMarkAllReadAlert,
					blogListBox, blogListBox.doMarkMallRead);
			}
			else
			{
				blogListBox.doMarkMallRead();
			}
		}
		
		/**
		 * update blogitem, set read, isStar, isKeepUnRead, etc.
		*/
		private function onBlogItemUpdate_handler(e:BlogItemEvent):void
		{
			if(e.updateType == BlogItemEvent.IS_STAR || e.updateType == BlogItemEvent.IS_KEEP)
			{
				dataProxy.updateBlogItem(e.blogItem);
			}
			else if(e.updateType == BlogItemEvent.IS_READ)
			{
				//firstly update blog item.
				dataProxy.readItem(e.blogItem);
				
				//change the newblogs label display.
				e.blogFetch.blogsource.newBlogs --;
				
				//update blogsource table
				if(e.blogFetch.blogsource.blogSourceId == -1)
				{
					//if blog listed by label, fetch blogsource by id
					var bs:BlogSourceVO = BlogSourceVO.getBlogSourceById(e.blogItem.blogSourceId, readerModelLocator.blogSource);
					bs.newBlogs --;
					dataProxy.updateBlogSource(bs);
				}
				else
				{
					dataProxy.updateBlogSource(e.blogFetch.blogsource);
				}
				
			}
		}
		
		/**
		 * update blogitems set to read.
		*/
		private function onBlogItemsUpdate_handler(e:BlogItemEvent):void
		{
			//change the newblogs label display.
			e.blogFetch.blogsource.newBlogs = 0;
			
			//update blogsource table
			if(e.blogFetch.blogsource.blogSourceId == -1)
			{
				//if blog listed by label, fetch blogsource by id
				var bs:BlogSourceVO = BlogSourceVO.getBlogSourceById(e.blogItem.blogSourceId, readerModelLocator.blogSource);
				bs.newBlogs = 0;
				dataProxy.updateBlogSource(bs);
			}
			else
				dataProxy.updateBlogSource(e.blogFetch.blogsource);
			
			//update blog item.
			if(e.blogItems && e.blogItems.length > 0)
				dataProxy.readAllItems(e.blogItems);
		}
		
		/**
		 * update blogsource, labelid, etc.
		*/
		private function onChangeBlogLabel_handler(e:BlogSourceEvent):void
		{
			dataProxy.updateBlogSource(e.blogSource);
		}
		
		/**
		 * unsubscribe blogsource, delete blogitem.
		*/
		private function onUnSubscribe_handler(e:BlogSourceEvent):void
		{
			var titleWindow:TitleWindowVO = new TitleWindowVO(readerModelLocator.airReader, dataProxy, Vector.<BlogSourceVO>([e.blogSource]));
			sendNotification(ApplicationFacade.REMOVE_SUBSCRIBE, titleWindow);
		}
		
		/**
		 * add deleted subscribe again.
		*/
		private function onQuickSubscribe_handler(e:BlogSourceEvent):void
		{
			dataProxy.addSubscribe(e.blogSource, true);
		}
		
		/**
		 * reset list operation combox.
		*/
		private function onListComboxChange_handler(e:Event = null):void
		{
			var isNullData:Boolean = true;
			if(blogListBox.blogSourceListDataProvider && blogListBox.blogSourceListDataProvider.length > 0)
			{
				isNullData = false;
			}
			blogListBox.blogItemComboBoxList = dataProxy.creatBlogItemComboBoxData(blogListBox.descAsc,  blogListBox.blogFetch, isNullData);
		}
		
		/**
		 * create a label panel and insert label into the database.
		*/
		private function onCreateTag_handler(e:BlogLabelEvent):void
		{
			var labelFetch:TitleWindowVO = new TitleWindowVO(readerModelLocator.airReader, dataProxy, Vector.<BlogSourceVO>([e.blogSource]));
			sendNotification(ApplicationFacade.LABEL_CREATE, labelFetch);
		}
		
		/**
		 * create a panel to change the given blogsource's name.
		*/
		private function onChangeBlogSourceName_handler(e:BlogSourceEvent):void
		{
			var labelFetch:TitleWindowVO = new TitleWindowVO(readerModelLocator.airReader, dataProxy, Vector.<BlogSourceVO>([e.blogSource]));
			sendNotification(ApplicationFacade.RENAME_SUBSCRIBE, labelFetch);
		}
		
		/**
		 * open the explorer to see the details.
		*/
		private function onOpenExplore_handler(e:BlogItemEvent):void
		{
			e.stopPropagation();
			sendNotification(ApplicationFacade.AIR_EXPLORER_OPEN, e.blogItem.link);
		}
		
		/**
		 * open writer to edit or share blog.
		*/
		private function onShareBlogItem_handler(e:BlogItemEvent):void
		{
			e.stopPropagation();
			var draft:BlogDraftVO = new BlogDraftVO();
			draft.title = e.blogItem.title;
			draft.description = e.blogItem.description;
			sendNotification(ApplicationFacade.WRITER_OPEN, draft, BlogWriter.VIEW_NEW_BLOG);
		}
	}
}